﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;

using VistaControls;

namespace PowerWaveAddin
{

    public partial class AccountConfigForm : Form
    {
        #region Fields and Properties
        private static UTF8Encoding encoding = new UTF8Encoding();

        private static VistaControls.Dwm.Margins glassMargins = new VistaControls.Dwm.Margins(10);

        private static AccountConfigForm instance;

        private static bool initialized;

        private static Color savedBlueColor;

        public bool UseWaveStorage
        {
            get
            {
                return this.useWaveStoreCheckbox.Checked;
            }
        }

        public StorageConfiguration ConfigurationObject
        {
            get { return this.CreateConfigObject(); }
        }

        public static AccountConfigForm Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new AccountConfigForm();
                }

                return instance;
            }
        } 
        #endregion

        #region Constructors
        private AccountConfigForm()
        {
            InitializeComponent();

            savedBlueColor = this.labeledDivider1.ForeColor;

            if (Aero.IsAeroSupported)
            {
                VistaControls.Dwm.GlassHelper.HandleBackgroundPainting(this, glassMargins);
                VistaControls.Dwm.GlassHelper.HandleFormMovementOnGlass(this, glassMargins);
                VistaControls.Dwm.DwmManager.EnableGlassFrame(this, glassMargins);
            }

            ToggleServerOptions(!this.useWaveStoreCheckbox.Checked);
        } 
        #endregion

        #region Event Handlers
        private void AccountConfigForm_Load(object sender, EventArgs e)
        {
            LoadConfiguration();
        }

        private void AccountConfig_Close(object sender, FormClosingEventArgs e)
        {
            
        }

        private void useWaveStoreCheckbox_CheckedChanged(object sender, EventArgs e)
        {
            ToggleServerOptions(!this.useWaveStoreCheckbox.Checked);
        }

        private void continueButton_Click(object sender, EventArgs e)
        {
            SaveConfiguration();
            this.Hide();
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            this.Hide();
        } 
        #endregion

        #region GUI Methods
        private void ToggleServerOptions(bool enabled)
        {
            this.hostLabel.Enabled = enabled;
            this.labelPort.Enabled = enabled;
            this.folderLabel.Enabled = enabled;
            this.urlLabel.Enabled = enabled;
            this.pwdLabel.Enabled = enabled;

            this.urlTextBox.Enabled = enabled;
            this.hostTextBox.Enabled = enabled;
            this.portTextBox.Enabled = enabled;
            this.folderTextBox.Enabled = enabled;

            this.userTextBox.Enabled = enabled;
            this.pwdTextBox.Enabled = enabled;

            this.savePwdCheckBox.Enabled = enabled;
            if (enabled)
                this.labeledDivider1.ForeColor = savedBlueColor;
            else
                this.labeledDivider1.ForeColor = Color.Gray;
        } 
        #endregion

        #region Serialization Methods
        private void SaveConfiguration()
        {
            string xmlData = SerializeConfiguration();
            try
            {
                StreamWriter writer = File.CreateText(
                    Path.Combine(
                        SystemHelper.AppDataFolder,
                        @"StorageConfiguration.xml"));

                writer.Write(xmlData);
                writer.Close();
            }
            catch (IOException e)
            {
                Aero.DisplayErrorMessage(
                    Properties.Resources.SerializeConfigCaption,
                    Properties.Resources.SerializeConfigMessage,
                    e.ToString());
            }
        }

        private void LoadConfiguration()
        {
            string xmlData = string.Empty;
            try
            {
                StreamReader reader = new StreamReader(
                   Path.Combine(
                       SystemHelper.AppDataFolder,
                       @"StorageConfiguration.xml"));
                xmlData = reader.ReadToEnd();
                reader.Close();
            }
            catch (IOException e)
            {
                Aero.DisplayErrorMessage(
                    Properties.Resources.DeserializeConfigCaption,
                    Properties.Resources.DeserializeConfigMessage,
                    e.ToString());
            }

            if (!string.IsNullOrEmpty(xmlData))
            {
                StorageConfiguration config = this.DeserializeConfiguration(xmlData);

                if (config == null)
                {
                    Aero.DisplayErrorMessage(
                        Properties.Resources.SerializeConfigCaption,
                        Properties.Resources.SerializeConfigMessage,
                        Properties.Resources.InvalidFileData + "\r\n" + xmlData);
                    return;
                }

                this.hostTextBox.Text = config.Host;
                this.portTextBox.Text = config.Port.ToString();
                this.folderTextBox.Text = config.Directory;
                this.urlTextBox.Text = config.HttpPath;
                this.userTextBox.Text = config.UserName;
                this.pwdTextBox.Text = config.Password;
                this.savePwdCheckBox.Checked = config.SavePassword;
                this.useWaveStoreCheckbox.Checked = config.UseGoogleHosting;
            }

        }

        public String SerializeConfiguration()
        {
            StorageConfiguration config = CreateConfigObject();
            if (!config.SavePassword)
            {
                config.Password = string.Empty;
            }

            try
            {
                String XmlizedString = null;
                MemoryStream memoryStream = new MemoryStream();
                XmlSerializer xs = new XmlSerializer(typeof(StorageConfiguration));
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

                xs.Serialize(xmlTextWriter, config);
                memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
                XmlizedString = encoding.GetString(memoryStream.ToArray());
                return XmlizedString;
            }
            catch (Exception e)
            {
                Aero.DisplayErrorMessage(
                    Properties.Resources.SerializeConfigCaption,
                    Properties.Resources.SerializeConfigMessage,
                    e.ToString());

                return null;
            }
        }

        internal StorageConfiguration DeserializeConfiguration(String pXmlizedString)
        {
            XmlSerializer xs = new XmlSerializer(typeof(StorageConfiguration));
            MemoryStream memoryStream = new MemoryStream(encoding.GetBytes(pXmlizedString));
            XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
            try
            {
                return xs.Deserialize(memoryStream) as StorageConfiguration;
            }
            catch (InvalidOperationException e)
            {
                Aero.DisplayErrorMessage(
                    Properties.Resources.SerializeConfigCaption,
                    Properties.Resources.SerializeConfigMessage,
                    e.InnerException.ToString());
                return null;
            }
        } 
        #endregion

        private StorageConfiguration CreateConfigObject()
        {
            StorageConfiguration config = new StorageConfiguration
            {
                UseGoogleHosting = this.useWaveStoreCheckbox.Checked,
                Host = this.hostTextBox.Text,
                Directory = this.folderTextBox.Text,
                Port = Int32.Parse(this.portTextBox.Text),
                HttpPath = urlTextBox.Text,
                UserName = this.userTextBox.Text,
                SavePassword = this.savePwdCheckBox.Checked,
                Password = this.pwdTextBox.Text
            };

            return config;
        }
    }

    /// <summary>
    /// Data config for establishing an SFTP connection
    /// </summary>
    [XmlRootAttribute(ElementName = "StorageConfiguration", IsNullable = false)]
    public class StorageConfiguration
    {
        public bool UseGoogleHosting { get; set; }
        public string Host { get; set; }
        public string Directory { get; set; }
        public int Port { get; set; }
        public string HttpPath { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        public bool SavePassword { get; set; }

        public bool HasMissingValues
        {
            get
            {
                return (
                    string.IsNullOrEmpty(this.UserName) ||
                    string.IsNullOrEmpty(this.Password) ||
                    string.IsNullOrEmpty(this.Host) ||
                    string.IsNullOrEmpty(this.Directory) ||
                    string.IsNullOrEmpty(this.HttpPath) ||
                    this.Port <= 0) ;

            }
        }
    }
}
